#ifndef INPUT_COMMAND_SERVER_H 
#define INPUT_COMMAND_SERVER_H

#include <glib.h>

#define INPUT_COMMAND_SERVER_PORT (19081)

/**
 * The input command message format MUST be:
 *   {command_name}\n
 *   {key0}\t{value0}\t{value1}\t...\t{valueN}\n
 *   {key1}\t{value0}\t{value1}\t...\t{valueN}\n
 *   ...
 *   {keyN}\t{value0}\t{value1}\t...\t{valueN}\n
 *   done\n
 */

typedef struct _NutstoreInputCommand NutstoreInputCommand;

/**
 * Input command handler. The handlers should never free command data
 */
typedef void (*NutstoreInputCommandHandler)(NutstoreInputCommand *);

/**
 * Input command
 */
struct _NutstoreInputCommand {
    // name and arguments
    gchar       *command_name;
    GHashTable  *command_args;

    // input command handler
    NutstoreInputCommandHandler handler;

    // user data of handler
    gpointer    user_data;
};

/**
 * connection state change hook
 */
typedef GHookFunc NutstoreInputCommandServerConnectHook;

/**
 * Input command server
 * As UDP is used to diliver messages, there is no connection.
 * We don't need the is_connected state and connection state change hook.
 */
typedef struct {
    // Handler dispatch table
    GHashTable  *dispatch_table;

    // NOT USED -- place here for future extension
    // Two hook list:
    //   1) hook of onconnect event
    //   2) hook of ondisconnect event
    GHookList   onconnect_hooklist;
    GHookList   ondisconnect_hooklist;
} NutstoreInputCommandServer;

/**
 * Setup input command server
 */
void nutstore_inputcmd_server_setup(NutstoreInputCommandServer *server);

/**
 * start input command server
 */
void nutstore_inputcmd_server_start(NutstoreInputCommandServer *server);

/**
 * Add input command handler
 */
void nutstore_inputcmd_server_add_handler(NutstoreInputCommandServer *server,
        const gchar *command_name,
        NutstoreInputCommandHandler handler,
        gboolean b_add_idle,
        gpointer user_data);

/** 
 * connection state change hook
 */
void nutstore_inputcmd_server_add_on_connect_hook(NutstoreInputCommandServer *server,
        NutstoreInputCommandServerConnectHook func,
        gpointer user_data);

void nutstore_inputcmd_server_add_on_disconnect_hook(NutstoreInputCommandServer *server,
        NutstoreInputCommandServerConnectHook func,
        gpointer user_data);

#endif

